package com.okay.monitoring

import android.content.Context
import android.graphics.*
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.ThreadLocalRandom
import kotlin.math.abs

/**

 * create nano on 2022/2/9 11:26

 */
class BarrageView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
    var mPaint = Paint()

    var basisX = 0f
    var basisY = 0f

    var barrageW = 300f//单一弹幕的宽
    var barrageH = 90f//单一弹幕的高

    /**
     * 设置每次飘动距离
     */
    val movingDistance = 3f

    /**
     * 当前view的坐标
     */
    var leftLay = 0f
    var topLay = 0f
    var rightLay = 0f
    var bottomLay = 0f

    var mobile = false //是否飘动

    var listData = CopyOnWriteArrayList<UserData>()

    init {
        Log.d("BarrageView", "init")
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        Log.d("BarrageView", "onMeasure")
        setMeasuredDimension(
            measureWidth(widthMeasureSpec),
            measureHeight(heightMeasureSpec)
        );//设置宽高为wrap_content的时候 给一个默认值
    }

    fun measureWidth(measureSpec: Int): Int {
        var specMode = MeasureSpec.getMode(measureSpec)
        var specSize = MeasureSpec.getSize(measureSpec)
        var result = 200
        if (specMode == MeasureSpec.AT_MOST) {//相当于我们设置为wrap_content
            result = specSize
        } else if (specMode == MeasureSpec.EXACTLY) {//相当于我们设置为match_parent或者为一个具体的值
            result = specSize
        }
        return result;
    }

    fun measureHeight(measureSpec: Int): Int {
        var specMode = MeasureSpec.getMode(measureSpec);
        var specSize = MeasureSpec.getSize(measureSpec);
        var result = 200
        if (specMode == MeasureSpec.AT_MOST) {
            result = specSize
        } else if (specMode == MeasureSpec.EXACTLY) {
            result = specSize
        }
        return result
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        Log.d("BarrageView", "onLayout")
        Log.d("BarrageView", "left：$left  top：$top  right：$right  bottom：$bottom")

        leftLay = left.toFloat()
        topLay = top.toFloat()
        rightLay = right.toFloat()
        bottomLay = bottom.toFloat()

        basisX = rightLay - leftLay
    }

    /**
     * 开始飘动
     */
    fun startView() {
        basisX = rightLay - leftLay
        mobile = true
        postInvalidate()
    }

    /**
     * 结束飘动
     */
    fun stopView() {
        mobile = false
    }

    /**
     * 暂停飘动或者激活
     */
    fun suspendedView() {
        mobile = !mobile
        postInvalidate()
    }

    /**
     * 添加飘屏数据
     */
    fun addData(userData: UserData) {

        synchronized(BarrageView::class.java) {

            var xx = basisX
            var yy = ThreadLocalRandom.current().nextInt(0, (bottomLay - topLay - barrageH).toInt())
                .toFloat()//随机取10~100之间的随机数
//        var yy = ThreadLocalRandom.current().nextInt(0, 180).toFloat()//随机取10~100之间的随机数
            var array = overlap(floatArrayOf(xx, yy))

            userData.locationX = array[0]
            userData.locationY = array[1]
            listData.add(userData)
            if (!mobile) {//如果飘屏停止了，就激活一下
                suspendedView()
            }
        }
    }

    /**
     * 判断弹窗是否有重叠，要是重叠就往后挪一下
     */
    fun overlap(floatArr: FloatArray): FloatArray {
        var isOverlap = false// 判断是否有重叠
        for (lists in listData) {
            if (lists.rect.intersects(
                    floatArr[0],
                    floatArr[1],
                    floatArr[0] + barrageW,
                    floatArr[1] + barrageH
                )
            ) {//判断两个弹幕有没有重叠，如果有重叠的话 就把当前要添加的弹幕往后挪一个弹幕的长度  再加上一个随机的位移，防止出现并排严重
                floatArr[0] = lists.rect.right + ThreadLocalRandom.current().nextInt(0, 50).toFloat()//随机取10~50之间的随机数
                isOverlap = true
                break
            } else {
                isOverlap = false
            }
        }

        if (isOverlap) {
            overlap(floatArr)
        }

        return floatArr
    }


    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
//        Log.d("BarrageView", "onDraw")

        if (listData.size < 1) {
            mobile = false
            return
        }

        for (element in listData) {
            drawS(canvas, element)
            var xx = element.locationX - movingDistance
            element.locationX = xx

            if (element.locationX < -barrageW) {
                listData.remove(element)
            }
        }

//        Log.d("BarrageView", "listData.size : ${listData.size}")
        if (!mobile) {
            return
        }

        invalidate()
    }

    fun drawS(canvas: Canvas?, userData: UserData) {

        var rect = RectF(
            userData.locationX,
            userData.locationY,
            userData.locationX + barrageW,
            userData.locationY + barrageH
        )
        userData.rect = rect
        if(userData.locationX>basisX){//如果在屏幕外边的话  就不继续渲染了
            return
        }

        mPaint.isAntiAlias = true //设置是否抗锯齿;
        mPaint.style = Paint.Style.STROKE //设置填充样式 Paint.Style.FILL_AND_STROKE 填充且描边  Paint.Style.STROKE 描边   Paint.Style.FILL 填充
        mPaint.color = Color.BLUE;//设置画笔颜色
        mPaint.strokeWidth = 2F;//设置画笔宽度

        //加载弹幕边框
        canvas?.drawRoundRect(rect, barrageH / 2, barrageH / 2, mPaint)

        mPaint.setStyle(Paint.Style.FILL)
        mPaint.setColor(Color.WHITE);//设置画笔颜色
        //设置弹幕背景颜色
        canvas?.drawRoundRect(rect, barrageH / 2, barrageH / 2, mPaint)

        mPaint.setColor(Color.GREEN);//设置画笔颜色
//        canvas?.drawCircle(
//            userData.locationX + (barrageH / 2),
//            userData.locationY + (barrageH / 2),
//            (barrageH / 2) - 10,
//            mPaint
//        )


        mPaint.textSize = 35f
        var fontMetrics = mPaint.fontMetrics
        var y = (barrageH / 2) / 2 + (abs(fontMetrics.ascent) - fontMetrics.descent) / 2
        //设置昵称
        canvas?.drawText(
            "我是一粒沙",
            userData.locationX + barrageH,
            userData.locationY + y + 5f,
            mPaint
        )

        mPaint.setTextSize(25f)
        var y1 = (barrageH / 2) / 2 + (Math.abs(fontMetrics.ascent) - fontMetrics.descent) / 2
        //设置个性签名
        canvas?.drawText(
            userData.signature,
            userData.locationX + barrageH,
            userData.locationY + y1 + (barrageH / 2),
            mPaint
        )
        mPaint.fontSpacing

        var b = userData.bitmap.sameAs(Bitmap.createBitmap(45, 45, Bitmap.Config.ARGB_8888))
        if (b) {//判断有没有头像，没有的话就去加载
            getBitmap(userData)//加载头像的bitmap
        } else {
            //设置头像
            canvas?.drawBitmap(
                userData.bitmap,
                userData.locationX + 10f,
                userData.locationY + 10f,
                mPaint
            )
        }
    }

    /**
     * 加载图片的
     */
    fun getBitmap(userData: UserData) {
        var requestOptions2 = RequestOptions.circleCropTransform()
        Glide.with(context).asBitmap()
            .load("https://cdn2.jianshu.io/assets/default_avatar/2-9636b13945b9ccf345bc98d0d81074eb.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/240/h/240")
            .apply(requestOptions2)
            .into(object : CustomTarget<Bitmap>() {
                override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                    userData.bitmap = Bitmap.createScaledBitmap(resource, 70, 70, true);
                }

                override fun onLoadCleared(placeholder: Drawable?) {
                }
            })
    }

    /**
     * 触摸点按下时的相对于屏幕的坐标
     */
    var  mDownInScreenX= 0f
    var  mDownInScreenY= 0f

    /**
     * 触摸点抬起时的相对于屏幕的坐标
     */
    var  mUpInScreenX= 0f
    var  mUpInScreenY= 0f


    override fun onTouchEvent(event: MotionEvent?): Boolean {

        when (event?.getAction()) {
            MotionEvent.ACTION_DOWN -> {
                Log.e("TAG", "LinearLayout onTouchEvent 按住")
                mDownInScreenX = event.getX()
                mDownInScreenY = event.getY()
            }
            MotionEvent.ACTION_UP -> {
                Log.e("TAG", "LinearLayout onTouchEvent 抬起")
                mUpInScreenX = event.getX()
                mUpInScreenY = event.getY()
                if(Math.abs(mUpInScreenX-mDownInScreenX)<5f && Math.abs(mUpInScreenY-mDownInScreenY)<5f){
                    Log.e("TAG", "LinearLayout onTouchEvent 点击了  哈哈哈")
                    for(list in listData){
                        if(list.rect.contains(mUpInScreenX,mUpInScreenY)){
                            onClickLisenter?.let {
                                it.clock(list)
                            }
                            break
                        }
                    }
                }
            }
            MotionEvent.ACTION_MOVE -> {
                Log.e("TAG", "LinearLayout onTouchEvent 移动")
            }
        }

        return true
    }
    
    fun setOnClickLisenter1(onClickLisenter: OnClickLisenter1){
        this.onClickLisenter = onClickLisenter
    }
    
    var onClickLisenter:OnClickLisenter1? = null

    interface OnClickLisenter1{
        fun clock(userData: UserData)
    }
}

